package xxy.com.yangproject.network;

import android.content.Context;

import com.blankj.utilcode.util.LogUtils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import io.reactivex.schedulers.Schedulers;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import xxy.com.yangproject.BuildConfig;
import xxy.com.yangproject.global.YangApplication;

public class NetWorkManager {
    public final static ObjectMapper objectMapper = new ObjectMapper();
    private static NetWorkManager instance ;

    static {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
    }

    public final GetRequestInterface getRequestInterface;

    public static NetWorkManager getInstance(){
        if (instance == null) {
            synchronized (NetWorkManager.class){
                if (instance == null) {
                    instance = new NetWorkManager();
                }
            }
        }
        return instance;
    }

    private NetWorkManager(){
        OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS)
                .readTimeout(5, TimeUnit.SECONDS)
                .addInterceptor(new CommonParamsIntercept(YangApplication.applictionContext));
        if (BuildConfig.DEBUG || Boolean.parseBoolean(BuildConfig.ENABLELOG)) {
            builder.addNetworkInterceptor(new LogIntercept());
        }
        getRequestInterface = new Retrofit.Builder().client(builder.build())
                .baseUrl("http://www.baidu.com")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
                .addConverterFactory(JacksonConverterFactory.create(objectMapper))
                .build().create(GetRequestInterface.class);
    }

    public static class CommonParamsIntercept implements Interceptor{   //header？  body？  to change?

        private Context context;
        private String appNames;
        private String channels;
        private String deviceImei;
        private String versionCode;

        @NotNull
        @Override
        public Response intercept(@NotNull Chain chain) throws IOException {   //从requestBody里取出数据，放入醒的容器formbodyBuilder里
            RequestBody requestBody = chain.request().body();
            if (requestBody instanceof FormBody) {
                final FormBody.Builder formbodyBuilder = new FormBody.Builder();
                for (int i = 0; i < ((FormBody) requestBody).size(); i++) {
                    final String key = ((FormBody) requestBody).name(i);
                    final String value = ((FormBody) requestBody).value(i);
                    formbodyBuilder.add(key, value);
                }
                return chain.proceed(chain.request().newBuilder().post(formbodyBuilder.build()).build());
            }
            return chain.proceed(chain.request());
        }

        public CommonParamsIntercept(Context context) {
            this.context = context.getApplicationContext();
        }
    }

    public static class LogIntercept implements Interceptor{


        @Override
        public Response intercept(Chain chain) throws IOException {   //输出有关网络请求的信息

            Response response = chain.proceed(chain.request());
            if (response.body() == null) {
                return response;
            }
            String bodyS = response.body().string();
            LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
            linkedHashMap.put("uri", chain.request().url().toString());
            linkedHashMap.put("RequestHeaders", chain.request().headers().toMultimap());
            RequestBody requestBody = chain.request().body();    //requesbody is important
            if (requestBody instanceof FormBody) {
                final HashMap<Object, Object> hashMap = new HashMap<>(((FormBody) requestBody).size());
                for (int i = 0; i < ((FormBody) requestBody).size(); i++) {
                    hashMap.put(((FormBody) requestBody).name(i), ((FormBody) requestBody).value(i));
                }
                linkedHashMap.put("FormBody", hashMap);
                LogUtils.e();
            }
            linkedHashMap.put("ResponseHeaders", response.headers().toMultimap());
            linkedHashMap.put("Response", bodyS);
            return response.newBuilder().body(ResponseBody.create(response.body().contentType(), bodyS)).build();
        }
    }
}
